package lt.liepasoft.locr.data;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

public class SymbolImage implements Image {
	
    /**
     * Width of the image, in pixels.
     */
    public final int width;
    
    /**
     * Height of the image, in pixels.
     */
    public final int height;
    
    /**
     * Total number of pixels in the image (<code>width*height</code>).
     */
    public final int npix;
    
    /**
     * Aspect ratio of the image (<code>width/height</code>).
     */
    public final float aspectRatio;
    
    public final Bounds bounds;	
    
    private final BitSet pixels;       

    /**
     * TODO: comment
     * @param pixels
     * @param width
     * @param height
     */
    public SymbolImage(int width, int height) {
        this.width = width;
        this.height = height;
        this.npix = width * height;
        this.aspectRatio = ((float) width) / ((float) height);
        this.bounds = new Bounds(0, 0, width, height);
        this.pixels = new BitSet(npix); 
    }
    

    
    /**
     * TODO: comment
     * @param pixels
     * @return
     */
    private int calculateBlackPixels(){
        int blackPixels=0;
        for (int i=0; i<npix; i++){
            if (pixels.get(i)){
                blackPixels++;
            }            
        }
        return blackPixels;
    }
        
    /**
     * Get the value of a pixel at a specific <code>x,y</code> position.
     * @param x The pixel's x position.
     * @param y The pixel's y position.
     * @return The value of the pixel.
     */
    public boolean getPixel(int x, int y){
        return pixels.get(getPixelIndex(x,y));
    }

    public final boolean getPixel(int index){
    	return pixels.get(index);
    }
    
    /**
     * Get the index of a pixel at a specific <code>x,y</code> position.
     * @param x The pixel's x position.
     * @param y The pixel's y position.
     * @return The pixel index (the index into the <code>pixels</code> array)
     * of the pixel.
     */
    public int getPixelIndex(int x, int y){
        return (y * width) + x;
    }    
    
    /**
     * TODO: comment
     * @param image
     * @return
     */
    public Float similarityRate(SymbolImage image){
    	if (image == null || image.width != width || image.height != height)
    		return Float.NaN;
    	
    	float equals=0;
        for (int i=0; i<image.npix; i++){
            if (image.pixels.get(i)){

//            if (s1.pixels.get(i) && s2.pixels.get(i)){
                if (image.pixels.get(i) == pixels.get(i)){
                    equals++;
                }
            }
        }
        //System.out.println(equals+" of "+s1.npix+" / "+s1.getBlackPixels());
        return equals/getBlackPixels();
    }
    
    public float getAspectRatio() {
        return aspectRatio;
    }

    public int getHeight() {
        return height;
    }

    public int getNpix() {
        return npix;
    }
    
    public int getWidth() {
        return width;
    }
    
    public int getRow(int index){
        return index/width;
    }
    
    public int getColumn(int index){
        return index%width;
    }
    
    public int getBlackPixels() {
		return calculateBlackPixels();
	}
    
    public int getWhitePixels(){
    	return npix - calculateBlackPixels();
    }

	public void setPixel(boolean value, int x, int y) {
		pixels.set(getPixelIndex(x, y), value);		
	}    
	
	public void setPixel(boolean value, int index){
		pixels.set(index, value);
	}
}
